package com.hpe.service;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import javax.mail.*;
import javax.mail.Flags.Flag;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.hpe.bean.SimpleAuthenticator;

/**
 * @Description
 * @date 2015年12月4日 下午5:09:04
 */
public class ImapReceiveMailService {
    private String imapServer = "imap.163.com";
    private String protocol = "imap";
    private String user = "18616385492";
    private String pwd = "kauygpezgjwmddgq";

    private String ftp_Url = "15.107.53.78";
    private int ftp_Port = 21;
    private String ftp_User = "FTP008";
    private String ftp_Pwd = "ZAQ.123456";
    private String save_Path = "C:\\Users\\shaxi\\Ftpfloder";

    SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");

    /**
     * @return
     * @Description get Connection
     */
    private Session getSession() {
        Session session = null;
        try {
            Authenticator auth = new SimpleAuthenticator(user, pwd);
            Properties props = new Properties();
            props.setProperty("mail.store.protocol", protocol);
            props.setProperty("mail.imap.host", imapServer);
            props.setProperty("mail.imap.port", "143");
            props.setProperty("mail.imap.auth", "true");
            session = Session.getInstance(props, auth);
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }
        return session;
    }

    /**
     * @throws Exception
     * @Description Get All Inbox Message
     */
    public void getInboxMessage() throws Exception {
        Session session = getSession();
        Store store = session.getStore("imap");
        store.connect();
        Folder folder = store.getFolder("INBOX");
        /*
         * Folder.READ_ONLY：只读权限 Folder.READ_WRITE：可读可写（可以修改邮件的状态）
		 */
        folder.open(Folder.READ_WRITE); // 打开收件箱

        System.out.println("邮件总数: " + folder.getMessageCount());
        System.out.println("未读邮件数: " + folder.getUnreadMessageCount());
        System.out.println("删除邮件数: " + folder.getDeletedMessageCount());
        System.out.println("新邮件: " + folder.getNewMessageCount());

        Message[] messages = folder.getMessages();
        for (int i = 0; i < messages.length; i++) {
            Flags flags = messages[i].getFlags();
            //			if (flags.contains(Flags.Flag.SEEN)) {
            //				System.out.println("这是一封已读邮件");
            //			} else {
            try {
                parseMessage(messages[i]);
            } catch (Exception e) {
                messages[i].setFlag(Flag.SEEN, false);
                e.printStackTrace();
            }
            //			}
        }
        // 释放资源
        folder.close(true);
        store.close();
    }

    /**
     * @param message
     * @throws Exception
     * @Description Parse Inbox Message
     */

    public void parseMessage(Message message) throws Exception {
        if (message == null) {
            return;
        }
        // 解析所有邮件
        // for (int i = 0, count = message.length; i < count; i++) {
        MimeMessage msg = (MimeMessage) message;
        System.out.println("------------------Parse " + msg.getMessageNumber() + "     message-------------------- ");
        System.out.println("Subject: " + getSubject(msg));
        System.out.println("SendTime:" + getSentDate(msg));
        boolean isContainerAttachment = isContainAttachment(msg);
        System.out.println("isContainerAttachment：" + isContainerAttachment);
        if (isContainerAttachment) {
            // 如果文件夹不存在则创建
            String savePath = "c:\\mailtmp\\";
            String savePath2 = savePath + getSentDate(msg) + "_" + msg.getSubject() + "_";
            File file = new File(savePath);
            if (!file.exists() && !file.isDirectory()) {
                file.mkdir();
            } else {
                System.out.println("directory exist!");
            }
            saveAttachment(msg, savePath2); // Save Attache
        }
    }

    /**
     * @param in
     * @param filename
     * @param fileFileName
     * @return
     * @throws IOException
     * @Description excel version
     */
    public Workbook openWorkbook(InputStream in, String filename, String fileFileName)
            throws IOException {
        Workbook wb = null;
        if (fileFileName.endsWith(".xlsx")) {
            wb = new XSSFWorkbook(in);// Excel 2007
        } else {
            wb = (Workbook) new HSSFWorkbook(in);// Excel 2003
        }
        return wb;
    }

    /**
     * @param part
     * @param destDir
     * @throws Exception
     * @Description judge the attachment type
     */
    public void saveAttachment(Part part, String destDir) throws Exception {
        if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent(); // 复杂体邮件
            // 复杂体邮件包含多个邮件体
            int partCount = multipart.getCount();
            for (int i = 0; i < partCount; i++) {
                // 获得复杂体邮件中其中一个邮件体
                BodyPart bodyPart = multipart.getBodyPart(i);
                // 某一个邮件体也有可能是由多个邮件体组成的复杂体
                String disp = bodyPart.getDisposition();
                if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) ||
                        disp.equalsIgnoreCase(Part.INLINE))) {
                    InputStream is = bodyPart.getInputStream();
                    // 保存附件
                    saveFile(is, destDir, decodeText(bodyPart.getFileName()));
                    // EXCLE TO XML
                    System.out.println(" ================= ");
                    ExcelReadService.getExcelDataToXml(destDir.concat((decodeText
                            (bodyPart.getFileName()))), ".xlsx");
                    System.out.println(destDir + (decodeText(bodyPart.getFileName()) + "+++++++++++++"));
                    // 上传到ftp
                    //					UpFileToFtp.upLoadFromProduction   (ftp_Url, ftp_Port, ftp_User, ftp_Pwd, save_Path,
                    //							format.format(new    Date()) + "_" + decodeText(bodyPart.getFileName()),
                    //							destDir.concat(decodeText(bodyPart.getFileName())));
                } else if (bodyPart.isMimeType("multipart/*")) {
                    saveAttachment(bodyPart, destDir);
                } else {
                    String contentType = bodyPart.getContentType();
                    if (contentType.indexOf("name") != -1 || contentType.indexOf
                            ("application") != -1) {
                        saveFile(bodyPart.getInputStream(), destDir, decodeText
                                (bodyPart.getFileName()));
                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            saveAttachment((Part) part.getContent(), destDir);
        }
    }

    /**
     * @param is
     * @param destDir
     * @param fileName
     * @throws Exception
     * @Description save attache file
     */
    public void saveFile(InputStream is, String destDir, String fileName) throws Exception {
        BufferedInputStream bis = new BufferedInputStream(is);
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File
                (destDir + fileName)));
        int len = -1;
        while ((len = bis.read()) != -1) {
            bos.write(len);
            bos.flush();
        }
        bos.close();
        bis.close();
        System.out.println(" =====保存 " + fileName + "成功========");
    }

    /**
     * @param encodeText
     * @return
     * @throws UnsupportedEncodingException
     * @Description
     */
    public String decodeText(String encodeText) throws UnsupportedEncodingException {
        if (encodeText == null || "".equals(encodeText)) {
            return "";
        } else {
            return MimeUtility.decodeText(encodeText);
        }

    }

    /**
     * @param part
     * @return
     * @throws MessagingException
     * @throws IOException
     * @Description judge is contain attache
     */
    public boolean isContainAttachment(Part part) throws MessagingException, IOException {
        boolean flag = false;
        if (part.isMimeType("multipart/*")) {
            MimeMultipart multipart = (MimeMultipart) part.getContent();
            int partCount = multipart.getCount();
            for (int i = 0; i < partCount; i++) {
                BodyPart bodyPart = multipart.getBodyPart(i);
                String disp = bodyPart.getDisposition();
                if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) ||
                        disp.equalsIgnoreCase(Part.INLINE))) {
                    flag = true;
                } else if (bodyPart.isMimeType("multipart/*")) {
                    flag = isContainAttachment(bodyPart);
                } else {
                    String contentType = bodyPart.getContentType();
                    if (contentType.indexOf("application") != -1) {
                        flag = true;
                    }

                    if (contentType.indexOf("name") != -1) {
                        flag = true;
                    }
                }
                if (flag)
                    break;
            }
        } else if (part.isMimeType("message/rfc822")) {
            flag = isContainAttachment((Part) part.getContent());
        }
        return flag;
    }

    /**
     * @param msg
     * @return
     * @throws Exception
     * @throws MessagingException
     * @Description get message subject
     */
    public String getSubject(MimeMessage msg) throws Exception, MessagingException {
        return MimeUtility.decodeText(msg.getSubject());
    }

    /**
     * @param msg
     * @return
     * @throws Exception
     * @Description get sendmessage date
     */
    public String getSentDate(MimeMessage msg) throws Exception {
        Date sentdate = msg.getSentDate();
        return format.format(sentdate);
    }
}
